package com.yunsom.testdemo;

import com.yunsom.testdemo.java8.stream.Student;
import com.yunsom.testdemo.util.DateUtil;
import com.yunsom.testdemo.util.StringUtil;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author Xbao
 * @version 1.0
 * @description
 * @date 2020/12/22 20:32
 */
public class TestApp {

  public static void main(String[] args) throws Exception {

    System.out.println(new Date());


    String date1 = "2022-11-11";
    String date2 = "2022-11-11 12:30:30";
    System.out.println(date1.length());
    System.out.println(date2.length());

    BigDecimal decimal1 = new BigDecimal(0);
    BigDecimal decimal2 = new BigDecimal(100.3);
    BigDecimal decimal3 = new BigDecimal(1);
    BigDecimal decimal4 = new BigDecimal(3);
    System.out.println(decimal1.divideToIntegralValue(decimal2).intValue());
    System.out.println(decimal2.divideToIntegralValue(decimal3).intValue());
    System.out.println(decimal2.divideToIntegralValue(decimal4).intValue());
    System.out.println(decimal2.remainder(decimal3).intValue());
    System.out.println(decimal2.remainder(decimal4).intValue());


    System.out.println(new Date());
    System.out.println(Instant.now());
    System.out.println(LocalDate.now());
    System.out.println(LocalDateTime.now());
    System.out.println(OffsetDateTime.now());
    System.out.println(ZonedDateTime.now());

    List<String> list1 = new ArrayList<>();
    list1.add("receive_date");
    list1.add("extend_field11");
    list1.add("extend_field1");
    list1.add("extend_field3");
    list1.add("extend_field20");
    list1.add("extend_field2");
    list1.add("extend_field13");
    list1.add("stock_status");
    for (String s : list1) {
      String[] extendFields = s.split("extend_field");
      if (extendFields.length <= 1) {
        System.out.println(extendFields[0]);
      } else {
        if (extendFields[1].length() == 1) {
          System.out.println("0" + extendFields[1]);
        } else {
          System.out.println(extendFields[1]);
        }
      }
    }
    System.out.println(new Date());


    BigDecimal a = new BigDecimal(3);
    BigDecimal b = new BigDecimal(5);

    System.out.println(a.divide(b).toString());
    System.out.println(a.divide(b).intValue());
//    byte[] bytes = new byte[]{(byte) 0xc9,0x03,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x7e,0x74};
//    System.out.println(binaryToHexString(bytes));

    byte[] totalActiveEnergy = new byte[]{0x01, 0x04, 0x02, 0x08, (byte)0xEE};

    final String crc2 = getCRC2(totalActiveEnergy, false);
    System.out.println(crc2);

    final String crc3 = getCRC16Result(binaryToHexString(totalActiveEnergy).replace(" ", ""));
    System.out.println(crc3);

    String str = "~~";
    String [] arr = str.split("~");
    System.out.println(arr.length);
    System.out.println(arr);

    List<String> cardNos = Arrays.asList("51022219750706622'","51022219750706622x","51022219750706622X'","2354907xX");

    final String s2 = cardNos.toString().replaceAll("\\[", "").replaceAll("]", "")
        .replaceAll("'", "").replaceAll(" ", "");
    System.out.println(s2);

    final String s1 = "51022219750706622".toUpperCase();
    System.out.println(s1);
    System.out.println(UUID.randomUUID().toString());

    System.out.println(Runtime.getRuntime().availableProcessors());
    String[] key_strs = "1231:{test:1}".split("");
    System.out.println(StringUtil.humpToLine("\"{\\\"extended_info\\\":{\\\"currentEntityElement\\\":\\\"qt_005ztzj\\\",\\\"dataLinkFilter\\\":[{\\\"elementId\\\":\\\"qt_005ztpt\\\",\\\"func\\\":\\\"equals\\\",\\\"type\\\":\\\"current_element\\\",\\\"val\\\":\\\"qt_005ztyz\\\"}],\\\"referEntityElement\\\":\\\"qt_005ztpt\\\",\\\"referEntityId\\\":\\\"0565abd6-eb5c-4e04-b1a7-d6a8f04cea2e\\\"},\\\"default_type\\\":\\\"link\\\"}\"\n"));

    Double diff = 0D;
    Student student = new Student();
    student.setScore(0.0);
    System.out.println(diff.equals(student.getScore()));


    System.out.println(new String("a").charAt(0));
    System.out.println(new String("b").charAt(0));

    final LocalDateTime localDateTime = DateUtil.parseLocalDateTime("2022-08-11");
    final String s = DateUtil.parseDateTimeStr(localDateTime);
    System.out.println(s);

    Double data1 = 12345d;
    Double data2 = 1234d;
    if (data1.compareTo(data2) < 0) {
      System.out.println("第二位数大！");
    }
    if (data1.compareTo(data2) == 0) {
      System.out.println("两位数一样大！");
    }
    if (data1.compareTo(data2) > 0) {
      System.out.println("第一位数大！");
    }

    System.out.println(Instant.MAX);

    System.out.println(System.getenv());
    System.out.println(System.getProperties());

    List<String> list= new ArrayList<>();
    list.parallelStream();

    System.out.println((short)1+3/2.0);
    int nThreads = Runtime.getRuntime().availableProcessors();
    System.out.println(nThreads);

    String deviceType = new String("2");
    checkDeviceType(deviceType);
    System.out.println(deviceType);

  }

  public static void checkCheckupRecordType(Boolean result){
    if(result){
      if(new Random().nextInt(3) > 2){
        result = true;
      } else {
        result = false;
      }
    }
    System.out.println("方法内result：" + result);
  }

  // 将字符串转成hash值
  public static String changeHash(String key) {
    // 数组大小一般取质数
    int arraySize = 11113;
    int hashCode = 0;
    String result=null;
    // 从字符串的左边开始计算
    for (int i = 0; i < key.length(); i++) {
      // 将获取到的字符串转换成数字，比如a的码值是97，则97-96=1
      int letterValue = key.charAt(i) - 96;
      // 就代表a的值，同理b=2；
      // 防止编码溢出，对每步结果都进行取模运算
      hashCode = ((hashCode << 5) + letterValue) % arraySize;
      result = String.valueOf(hashCode);
    }
    return result;
  }
  


  /*
  根据时间范围获取时间段起始点小时 04:00-07:00 23:00-05:00
   */
  public static List<Integer> getHoursByTimeRange(List<String> timeRanges){
    List<Integer> result = new ArrayList<>();
    for (String timeRange : timeRanges) {
      try{
        final String[] hours = timeRange.split("-");
        final String startTime = hours[0];
        final String[] startHourArray = startTime.split(":");
        final Integer startHour = Integer.parseInt(startHourArray[0]);

        final String endTime = hours[1];
        final String[] endHourArray = endTime.split(":");
        final Integer endHour = Integer.parseInt(endHourArray[0]);

        if(startHour < endHour){
          for (int i = startHour; i < endHour; i++) {
            result.add(i);
          }
        } else {
          for (int i = startHour; i< 24; i++) {
            result.add(i);
          }
          for (int i = 0; i < endHour; i++) {
            result.add(i);
          }
        }

      } catch (Exception e){
      }
    }
    return result;
  }

  /*
    获取集合中重复的元素
     */
  public static List<String> hasDuplicateElement(List<String> list) {

    List<String> result = new ArrayList<>();
    Map<String,Integer> map = new HashMap<>(100);

    for (String s : list) {
      if(map.containsKey(s)){
        map.put(s, map.get(s) + 1);
      } else {
        map.put(s, 1);
      }
    }

    for (Entry<String, Integer> entry : map.entrySet()) {
      if(entry.getValue() > 1){
        result.add(entry.getKey());
      }
    }
    return result;

  }


  public static void testGit(){

    Calendar now = Calendar.getInstance();
    int i = now.get(Calendar.MONTH);
    System.out.println(i);
    now.set(Calendar.MONTH, i+1);
    System.out.println(now.get(Calendar.MONTH));
  }

  /*
  //        ModBus 通信协议的 CRC ( 冗余循环校验码含2个字节, 即 16 位二进制数。
//        CRC 码由发送设备计算, 放置于所发送信息帧的尾部。
//        接收信息设备再重新计算所接收信息 (除 CRC 之外的部分）的 CRC,
//        比较计算得到的 CRC 是否与接收到CRC相符, 如果两者不相符, 则认为数据出错。
//
//        1) 预置 1 个 16 位的寄存器为十六进制FFFF(即全为 1) , 称此寄存器为 CRC寄存器。
//        2) 把第一个 8 位二进制数据 (通信信息帧的第一个字节) 与 16 位的 CRC寄存器的低 8 位相异或, 把结果放于 CRC寄存器。
//        3) 把 CRC 寄存器的内容右移一位( 朝低位)用 0 填补最高位, 并检查右移后的移出位。
//        4) 如果移出位为 0, 重复第 3 步 ( 再次右移一位); 如果移出位为 1, CRC 寄存器与多项式A001 ( 1010 0000 0000 0001) 进行异或。
//        5) 重复步骤 3 和步骤 4, 直到右移 8 次,这样整个8位数据全部进行了处理。
//        6) 重复步骤 2 到步骤 5, 进行通信信息帧下一个字节的处理。
//        7) 将该通信信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换。
//        8) 最后得到的 CRC寄存器内容即为 CRC码。
   */
  public static String getCRC2(byte[] bytes, boolean isHighDigitAhead) {

    int CRC = 0x0000ffff;
    int POLYNOMIAL = 0x0000a001;

    int i, j;
    for (i = 0; i < bytes.length; i++) {
      CRC ^= (int) bytes[i];
      for (j = 0; j < 8; j++) {
        if ((CRC & 0x00000001) == 1) {
          CRC >>= 1;
          CRC ^= POLYNOMIAL;
        } else {
          CRC >>= 1;
        }
      }
    }

    if(!isHighDigitAhead){
      CRC = ( (CRC & 0x0000FF00) >> 8) | ( (CRC & 0x000000FF ) << 8);
    }
    return String.format("%04X", CRC);
  }

  /**
   * 将十六进制的字符串转换成字节数组
   *
   * @param hexString
   * @return
   */
  public static byte[] hexStrToBinaryStr(String hexString) {

    if (Objects.isNull(hexString)) {
      return null;
    }

    hexString = hexString.replaceAll(" ", "");

    int len = hexString.length();
    int index = 0;

    byte[] bytes = new byte[len / 2];

    while (index < len) {

      String sub = hexString.substring(index, index + 2);

      bytes[index/2] = (byte)Integer.parseInt(sub,16);

      index += 2;
    }


    return bytes;
  }

  /**
   * 将字节数组转换成十六进制的字符串
   *
   * @return
   */
  public static String binaryToHexString(byte[] bytes) {
    String hexStr = "0123456789ABCDEF";
    String result = "";
    String hex = "";
    for (byte b : bytes) {
      hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
      hex += String.valueOf(hexStr.charAt(b & 0x0F));
      result += hex + " ";
    }
    return result;
  }

  public static String parseStartOfDayForTenMinuteSchedule(Date date) {

    Calendar ca = Calendar.getInstance();
    ca.setTime(date);
    final int hour = ca.get(Calendar.HOUR_OF_DAY);
    final int minute = ca.get(Calendar.MINUTE);

    // 如果是第二天
    if(hour == 0 && minute < 10){
      ca.set(Calendar.DATE, ca.get(Calendar.DATE) - 1);
    }

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");

    return dateFormat.format(ca.getTime());
  }


  public static void checkDeviceType(String b){

    b = "1";
    System.out.println("--");

  }

  private static String getCRC16Result(String s){
    int CRC = 0x0000ffff;
    for (int i=0;i<s.length();i=i+2){
      int CRCL=CRC&0x000000FF;//低八位
      int CRCH=CRC&0x0000FF00;//高八位
      String CRCIn = s.substring(i,i+2);
//            System.out.println(CRCIn);
      int a = Integer.parseInt(CRCIn,16);//待处理数据转16进制
      CRC=CRCH+CRCL^a;
      for(int j=0;j<8;j++){
        if((CRC&0x0001)==0){
          CRC=CRC>>1;
        }else {
          CRC>>=1;
          CRC=CRC^0xA001;
        }
      }
    }
    //      交换
//        int CRCL=CRC&0x000000FF;//低八位
//        int CRCH=CRC&0x0000FF00;//高八位
//        System.out.println(Integer.toHexString(CRCL));
//        System.out.println(Integer.toHexString(CRC));
//        CRC=CRCL<<8|CRCH>>8;//最好用按位与，别用加
//        System.out.println(Integer.toHexString(CRC));
    return Integer.toHexString(CRC);
  }

}
